<?php

namespace App\Services\Game;
use App\DTOS\Admin\PayOrderInsertDTO;
use App\DTOS\NeiGouDTO;
use App\DTOS\YiyouOrderDTO;
use App\Exceptions\ServiceException;
use App\Models\Customer;
use App\Models\Game\GameGoods;
use App\Models\Game\PayOrder;
use Illuminate\Support\Facades\Log;

class YiyouService
{

    private PayOrderService $payOrderService;
    private NeigouService $NeigouService;

    /*
     *

唯恋易游
渠道标识：wlyiyou
名称：猎人王
运行端：安卓+苹果
包名：com.wlyiyou.lrw
包号
安卓：10042001
IOS：10043002

参数
安卓
APP_ID:141
APP_KEY:5b24ba687a406b54a84bdb8fea1c160e
CLIENT_ID:40
CLIENT_KEY:d1bb7cde2707e21bca290a044ec52e01

IOS
APP_ID:142
APP_KEY:09219f20596619dd9826f63629c10d30
CLIENT_ID:41
CLIENT_KEY:b34352184b61aef7a39f6f7f54c723b2
协议:hyiyouy.com14241

     *
     * */
    // 安卓的
    private $appId = "141";
    private $appKey = "5b24ba687a406b54a84bdb8fea1c160e";
    private $clientId = "40";
    private $clientKey = "d1bb7cde2707e21bca290a044ec52e01";

    //苹果的
    private $iosAppId = "142";
    private $iosAppKey = "09219f20596619dd9826f63629c10d30";
    private $iosClientId = "41";
    private $iosClientKey = "b34352184b61aef7a39f6f7f54c723b2";

    /**
     * YiyouService constructor.
     * @param PayOrderService $payOrderService
     * @param NeigouService $NeigouService
     */
    public function __construct(PayOrderService $payOrderService,NeigouService $NeigouService)
    {
        $this->payOrderService = $payOrderService;
        $this->NeigouService = $NeigouService;
    }

    public function login($accessToken){
        $arr = explode("_",$accessToken);
        $memId = $arr[0];
        $userToken = $arr[1];
        $url = "https://sdk.yiyouy.com/cp/user/check";
        $data = [
            'app_id'=>$this->appId,
            'mem_id'=>$memId,
            'user_token'=>$userToken,
        ];
        $data['sign'] = $this->getSign($memId , $userToken);
        $response = httpPost($url,dataToParams($data));
        $resData = json_decode($response,true);
        if (data_get($resData,'status') !=1 ){
            throw new ServiceException(data_get($response,'msg'));
        }
        return [
            'mem_id'=>$memId
        ];
    }

    public function getSign($memId , $userToken) //登录专用的签名
    {
        $urlStr = "app_id={$this->appId}&mem_id={$memId}&user_token={$userToken}&app_key={$this->appKey}";
        return md5($urlStr);
    }


    /**
     * @param YiyouOrderDTO $DTO
     * @return string
     * @throws ServiceException
     */
    public function createOrder(YiyouOrderDTO $DTO){

        $orderNo = 'yiyou_'.getSnowFlakeId();
        $goodsId = $DTO->getGoodsId();
        $gameGoods = GameGoods::query()->find($goodsId);
        $roleId = $DTO->getRoleId();
        //记录到订单表 begin
        $PayOrderInsertDTO = new PayOrderInsertDTO();
        $PayOrderInsertDTO->setOrderNo($orderNo);
        $PayOrderInsertDTO->setName($gameGoods->name);
        $PayOrderInsertDTO->setDetail($gameGoods->detail);
        $PayOrderInsertDTO->setStatus(0);
        $PayOrderInsertDTO->setGameArea($DTO->getServerId());
        $PayOrderInsertDTO->setFrontFee($DTO->getPriceFee());
        $PayOrderInsertDTO->setFee($gameGoods->price_fee);
        $PayOrderInsertDTO->setRoleId($roleId);
        $PayOrderInsertDTO->setGoodsId($goodsId);
        $PayOrderInsertDTO->setNumber(1);
        $PayOrderInsertDTO->setCreatedAt(now()->format("Y-m-d H:i:s"));
        $PayOrderInsertDTO->setCustomerId($DTO->getCustomerId());
        $this->payOrderService->createOrder($PayOrderInsertDTO);

        return $orderNo;
    }

    /**
     * @param string $params
     * @return bool
     * @throws ServiceException
     */
    public function payCallback($params)
    {
        $data = urlencodedStrToArray($params);
        //计算签名
        $appId0 = data_get($data,'app_id');
        if ($appId0 == $this->appId){ //安卓
            $appKey = $this->appKey;
        } else if($appId0 == $this->iosAppId){ //IOS
            $appKey = $this->iosAppKey;
        } else {
            throw new ServiceException("appId error");
        }
        $params1 = preg_replace("/(.*?)sign=.*/","$1app_key=".$appKey,$params);
        $sign = $data['sign'];
        $sign1 = md5($params1);

        if ($sign != $sign1) {
            Log::error("sign:". $sign );
            Log::error("sign1:". $sign1 );
            throw new ServiceException('签名错误');
        }

        $cp_order_id = $data['cp_order_id']; //公司内部订单号
        $order_id = $data['order_id']; //平台订单号
        $order_status = $data['order_status'];
        $product_id = $data['product_id'];
        $product_price = $data['product_price'];

        if ($order_status!=2){
            throw new ServiceException('订单未支付');
        }
        $payOrder = PayOrder::query()->where('order_no',$cp_order_id)->first();
        $payOrder->lockForUpdate();
        if (!$payOrder){
            throw new ServiceException('此订单不存在');
        }
        if($payOrder->status==1){
            throw new ServiceException('内部订单已经支付');
        }
        $gameGoods = GameGoods::query()->find($product_id);
        if (!$gameGoods){
            throw new ServiceException('商品不存在');
        }

        // $status
        $yiyouFee = (int)($product_price*100);
        if ($yiyouFee != $payOrder->fee){
            throw new ServiceException('商品价格不一致');
        }

        $payOrder->status = 1;
        $payOrder->channel_order_no = $order_id;
        $payOrder->save();

        $typeValue = $gameGoods->type_value;
        //发货
        $neiGouDTO = new NeiGouDTO();
        $neiGouDTO->setGameArea($payOrder->game_area);
        $neiGouDTO->setNumber($payOrder->number);
        $neiGouDTO->setRoleId($payOrder->role_id);
        $neiGouDTO->setOrderNo($payOrder->order_no);
        $neiGouDTO->setGoodsId($payOrder->goods_id);
        $neiGouDTO->setTypeValue($typeValue);
        try {
            $this->NeigouService->pushToServer($neiGouDTO);
            $payOrder->updated_at = date("Y-m-d H:i:s");
            $payOrder->push_status = 1;
            $payOrder->save();
        } catch (ServiceException $e) {
            Log::error("易游支付回调后,商品发货报错:" . $e->getMessage());
            $payOrder->updated_at = date("Y-m-d H:i:s");
            $payOrder->push_status = -1;
            $payOrder->save();
        }

        return true;
    }

}
